package org.jdns.jfreechess.server;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundMessageHandlerAdapter;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.inject.Inject;

import org.jdns.jfreechess.timeseal.TimesealedMessage;

/**
 * This handler is responsible introducing the {@link CommandScoped} context into the Netty
 * pipeline. Handlers downstream of this handler will be able to inject the current {@link Channel}
 * and can access the channel's attributes (e.g. the current user).
 */
public class SessionScopeHandler extends ChannelInboundMessageHandlerAdapter<TimesealedMessage> {
  @Inject
  private Logger logger;

  @Override
  public void messageReceived(ChannelHandlerContext ctx, TimesealedMessage msg) throws Exception {
    ChessServerServingModule.scope.enter();
    try {
      ChessServerServingModule.scope.seed(Channel.class, ctx.channel());
      ChessServerServingModule.scope.seed(TimesealedMessage.class, msg);
      ctx.nextInboundMessageBuffer().add(msg);
      ctx.fireInboundBufferUpdated();
    } finally {
      ChessServerServingModule.scope.exit();
    }
  }

  @Override
  public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
    ChessServerServingModule.scope.enter();
    try {
      ChessServerServingModule.scope.seed(Channel.class, ctx.channel());
      ctx.fireChannelUnregistered();
    } finally {
      ChessServerServingModule.scope.exit();
    }
  }

  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    logger.log(Level.WARNING, "Unexpected exception: ", cause);
    ctx.close();
  }
}